Step 3 - Export and use the API to set the application theme

In this step of the tutorial you export the kzb files for both baked themes (defined in the Car variant theme group) and non-baked themes (defined in the Cluster theme theme group), and use the Kanzi Engine API to enable the user to change the non-baked themes in the application.

Export kzb files

In this section you first set in the Kanzi Studio project how you want to export the themes in the project, then you export the themes.

This section shows how to export themes you defined in the Cluster theme theme group with themes you defined in the Car variant theme group as theme packs. A Theme resource pack is a kzb file which contains only the resources for a selected Theme. Use this approach when the storage or memory on your target device is limited, but you want to change the application theme at runtime without having to load additional kzb files. For example, with this approach you can create from one Kanzi Studio project applications for two car variants (Gasoline and Hybrid), where each has two themes (Classic and Modern) between which you can switch in the application.

This is just one of the approaches of how you can export themes from your project. To find the approach that is most suitable for your product and target hardware, see Exporting Themes.

To export kzb files:

  1. From the Prefabs drag the Theme selector prefab to the Project and drop it on the RootPage node.
    In the next section you use the Kanzi Engine API to create a button which enables users to change the application theme.
  2. In the Library > Themes select the Car variant theme group and in the Properties set:
  3. In the Library > Themes select the Cluster theme theme group and in the Properties set the Selected Theme property to Cluster theme/DefaultValues.
  4. In the Library > Themes double-click the Cluster theme theme group to open it in the Theme Editor and click next to the Classic and Modern themes.
    This way you mark a theme to export theme resources. When you enable the exporting of Theme resources the icon in the Theme column turns blue and Kanzi Studio exports the resources used in that Theme.
  5. Select File > Export > Export Baked Theme Binaries and in the Themes and Locales to Bake on Export window disable the Export Main Kzb setting.
    In the Themes and Locales to Bake on Export window you can select which baked themes in the Car variant theme group you want to export.
    Click Export.

    Kanzi Studio creates:
  6. In a text editor:

Add code to change the cluster theme

In this section you add the application code to start the application with the Classic theme and create a message handler which you add to the Theme selector Button 2D node to switch between the two themes you created in the Cluster theme theme group.

To add code to change the cluster theme:

  1. In Visual Studio open the Visual Studio solution for your application located in Application/configs/platforms/win32.
    NOTE

    If you open the tutorial solution in Visual Studio 2017, when asked to retarget the project to the latest Microsoft toolset, click Cancel.

  2. In the Theming class create:
    class Theming : public ExampleApplication
    {
        // Structure describing a theme.
        struct ThemeDescriptor
        {
            explicit ThemeDescriptor(const string& name, const string& url):
                m_name(name),
                m_url(url)
            {
            }
    
            // The name of the theme.
            string m_name;
            // The kzb file URL of the theme.
            string m_url;
        };
    
        // Collection of all theme descriptions.
        vector<ThemeDescriptor> m_themes;
    
        // The index of the currently active theme.
        int m_activeThemeIndex;
    
        // The name of the baked theme to load.
        static const string m_carVariant;
    
    ...
    
    }
  3. After the Theming class use the m_carVariant variable you created in the previous step, to set which car variant you want to load at application startup.
    // Select which baked theme to use.
    // To start the application for the Hybrid car variant, set to 0.
    // To start the application for the Gasoline car variant, set to 1.
    #if 1
    const string Theming::m_carVariant = "Gasoline";
    #else
    const string Theming::m_carVariant = "Hybrid";
    #endif
  4. In the onConfigure() function use the .kzb.cfg file Kanzi Studio creates when exporting kzb file to load the application with the baked theme you can set in the previous step.
        virtual void onConfigure(ApplicationProperties& configuration) KZ_OVERRIDE
        {
            configuration.binaryName = "./Car variant=" + m_carVariant + "/theming.kzb.cfg";
            configuration.defaultWindowProperties.width = 1920;
            configuration.defaultWindowProperties.height = 720;
        }
  5. In the onProjectLoaded() function
        virtual void onProjectLoaded() KZ_OVERRIDE
        {
            // Add names and URLs for all themes.
            m_themes.push_back(ThemeDescriptor("Classic", "kzb://theming/Themes/Cluster theme/Classic"));
            m_themes.push_back(ThemeDescriptor("Modern", "kzb://theming/Themes/Cluster theme/Modern"));
    
            // Load metadata from all kzb files which contain theme resources.
            ResourceManager* resourceManager = getResourceManager();
            resourceManager->addKzbFile("./Car variant=" + m_carVariant + "/Theme_packs/Cluster theme=Classic.kzb");
            resourceManager->addKzbFile("./Car variant=" + m_carVariant + "/Theme_packs/Cluster theme=Modern.kzb");
    
            // Activate the first theme at application startup.
            m_activeThemeIndex = -1;
            changeToNextTheme();
        }
  6. After the onProjectLoaded() function create a function you use to activate the next theme in your application.
        // Activates the next theme.
        void changeToNextTheme()
        {
            // Get the Text Block 2D node in the Theme selector Button 2D node so that you can change the text to show the name of the next theme.
            Button2DSharedPtr themeSelectorButton = getRoot()->lookupNode<Button2D>("Theme selector");
            TextBlock2DSharedPtr selectorThemeTextBlock = themeSelectorButton->lookupNode<TextBlock2D>("#Next theme name");
    
            // Get the descriptors for the next theme and the theme following the next theme.
            const int nextThemeIndex = (m_activeThemeIndex + 1) % m_themes.size();
            const int followingThemeIndex = (m_activeThemeIndex + 2) % m_themes.size();
            const ThemeDescriptor& nextTheme = m_themes.at(nextThemeIndex);
            const ThemeDescriptor& followingTheme = m_themes.at(followingThemeIndex);
    
            // Set the name of the following theme.
            selectorThemeTextBlock->setText(followingTheme.m_name);
    
            // Set the application theme to the next theme.
            getScreen()->activateTheme(nextTheme.m_url);
            m_activeThemeIndex = nextThemeIndex;
        }
    
  7. In the Theming class after the onProjectLoaded() function create the onChangeThemeButtonClicked event handler where you define how the application reacts when user clicks the Theme selector button in the application.
        // This message handler defines how the application reacts when the user clicks the Theme selector button in the application.
        void onChangeThemeButtonClicked(ButtonConcept::ClickedMessageArguments& /* messageArguments */)
        {
            changeToNextTheme();
        }
    
  8. In the onProjectLoaded() function after loading the metadata from theme kzb files add the message handler you created in the previous step to the Theme selector node.
        virtual void onProjectLoaded() KZ_OVERRIDE
        {
    
        ...
    
            // Register the message handler for the Button: Click message used by the Theme selector node.
            Button2DSharedPtr themeSelectorButton = getRoot()->lookupNode<Button2D>("Theme selector");
            themeSelectorButton->addMessageHandler(ButtonConcept::ClickedMessage, bind(&Theming::onChangeThemeButtonClicked, this, placeholders::_1));
    
        ...
    
        }
  9. In Visual Studio select one of the solution configurations for your version of Visual Studio and run your application.
    For example, if you are still developing your application, select the GL_vs2015_Debug configuration. If you want to create a production version of your Kanzi application, select one of the available release configurations.

In the application when you click the Theme selector button, you switch between the Classic and Modern cluster themes which you defined in the Cluster theme theme group.


< PREVIOUS STEP

What's next?

In this tutorial you learned how to theme a Kanzi application to create different appearance of the same application and how to use a single Kanzi Studio project for more than one variant of your product. To take this tutorial further you can create assets for additional cluster themes and car variants. You can also:

See also

To find out more about how to create themes for your Kanzi applications, see Theming your applications.

To learn more about the different options for exporting themes from your Kanzi Studio project, see Exporting Themes.

To learn how to create and use styles, see Using styles.

To learn more about using state managers in your Kanzi applications, see Tutorial: Use state managers to control your application and Using state managers.

To learn more about Prefab Placeholder and Prefab View nodes, and how to use them, see Using prefabs.